package com.lile.IO_01.Exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo {

	public static void main(String[] args) {
		// test1();
		// tryCacheFinally();
		// multiException1();
		// multiException2();
		// multiException3();
		// throwsTest();
		// exceptionTypes();
		exceptionMessage();
	}

	/*
	 * 异常：程序在运行的过程中，出现了不正常的情况。 举例： 班长骑着自行车去旅游 一开始就要检查的：漏气了，链子掉了 发现没有问题，就上路，一路顺风。
	 * 山路，中间很铺好的水泥路，两边有尖尖小石子， 如果，他正常的话，走水泥路就好了，肯定是没有任何问题的，
	 * 但是呢，他偏偏不走寻常路，走上小石子，车爆胎了。 他怕爆胎没走石子路，走的是水泥路，但是走到一半，发现山路塌陷了，班长只好回来了。 分类： 错误
	 * Error 合理的应用程序不应该试图捕获的严重问题。说明我们不需要处理这种问题，比如说内存溢出。 异常 Exception
	 * 合理的应用程序想要捕获的条件，说明是需要我们进行处理的。 编译时期异常 非RuntimeException 这是我们必须要处理的异常。
	 * 运行时期异常 RuntimeException 这种异常，一般我们也是不需要处理的。一般出现这样的问题，应该是我们写的代码出问题了。
	 * 
	 * JVM的默认处理方案: 程序出现了异常，如果我们没有做任何处理，jvm做出了默认的处理。
	 * 把异常的类名，产生的原因以及出现的位置等信息显示在了控制台。 并让程序从这里结束了。
	 */
	public static void test1() {
		int a = 10;
		int b = 0;
		System.out.println(a / b); // Exception in thread "main"
									// java.lang.ArithmeticException: / by zero
	}

	/*
	 * java中我们如何处理异常呢? A:try⋯catch⋯finally B:throws
	 * 
	 * try⋯catch⋯finally格式 try { 可能出现问题的代码 }catch(异常类名 变量) { 针对问题的处理 }finally {
	 * 释放资源的代码 }
	 * 
	 * finally等会在讲，所以，这个时候，我们先使用简单的格式： try { 可能出现问题的代码 }catch(异常类名 变量) { 针对问题的处理
	 * }
	 * 
	 * 尽可能的把可能出现问题的代码用try包含，如果你判断不了哪些有问题，可以多包含一些。
	 */
	public static void tryCacheFinally() {
		int a = 10;
		int b = 0;
		try {
			System.out.println(a / b);
		} catch (ArithmeticException e) {
			// 实际开发的时候，应该给出的是页面形式的提示
			System.out.println("除数不能为0");
		}
	}

	/*
	 * 多个异常的情况： A:针对每个异常，给出一个处理 B:try...catch...catch...catch... 注意：
	 * a:一旦try里面的代码有问题，就不再执行try里面的内容，和catch里面的内容依次的匹配，一旦有一个匹配，其他的不执行。
	 * b:如果异常是平级关系，谁先谁后无所谓。 如果异常不是平级关系，子先父后。
	 * 
	 * JDK7的新特性：针对平级关系的 catch(异常1 | 异常2 | 异常3 ... e) {}
	 */
	public static void multiException1() {
		int a = 10;
		int b = 0;
		try {
			System.out.println(a / b);
		} catch (ArithmeticException e) {
			System.out.println("除数不能为0");
		}

		int[] arr = { 1, 2, 3 };
		try {
			System.out.println(arr[3]);
		} catch (ArrayIndexOutOfBoundsException e) {
			// TODO: handle exception
			System.out.println("索引越界异常");
		}
	}

	public static void multiException2() {
		int a = 10;
		int b = 0;
		int[] arr = { 1, 2, 3 };

		try {
			System.out.println(a / b);
			System.out.println(arr[3]);
		} catch (ArithmeticException e) {
			System.out.println("除数不能为0");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("索引越界异常");
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("程序出问题了");
		}
	}

	public static void multiException3() {
		int a = 10;
		int b = 0;
		int[] arr = { 1, 2, 3 };

		try {
			System.out.println(a / b);
			System.out.println(arr[3]);
		} catch (Exception e) {
			System.out.println("程序出问题了");
		}
	}

	/*
	 * throws：它就是在方法上声明异常，告诉你，我这个方法有问题。你使用的时候要注意了。
	 */
	public static void throwsTest() throws ArithmeticException {
		int a = 10;
		int b = 0;
		System.out.println(a / b);
	}

	/*
	 * Java中的异常被分为两大类：编译时异常和运行时异常。所有的RuntimeException类及其子类的实例被称为运行时异常，
	 * 其他的异常就是编译时异常 编译时异常 Java程序必须显示处理，否则程序就会发生错误，无法通过编译 运行时异常
	 * 无需显示处理，也可以和编译时异常一样处理
	 *
	 * 处理异常的方式特别的简单：会点击鼠标即可。
	 */
	public static void exceptionTypes() {
		String s = "2015-04-03 10:37:45";

		Date d = null;
		try {
			d = stringToDate(s);
			System.out.println(2 / 0);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		System.out.println(d);
	}

	public static Date stringToDate(String s) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = sdf.parse(s);
		return date;
	}

	/*
	 * getMessage():获取异常信息，返回字符串。 toString():获取异常类名和异常信息，返回字符串。
	 * printStackTrace():获取异常类名和异常信息，以及异常出现在程序中的位置。返回值void。
	 */
	public static void exceptionMessage() {
		int a = 10;
		int b = 0;
		try {
			System.out.println(a / b); // 从哪里产生异常，就会在哪里创建一个异常的对象。new
										// ArithmeticException();
										// 然后，拿着该异常对象，到catch里面去匹配。
		} catch (ArithmeticException e) { // ArithmeticException e = new
											// ArithmeticException();
			// System.out.println(e.toString());
			// System.out.println("除数不能为0");

			System.out.println(e.getMessage()); // by zero
			System.out.println(e.toString());
			e.printStackTrace();
		}

	}

}
